home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Hot Mix 17
/
Hot Mix 17.iso
/
HM17_SGI
/
research
/
lib
/
svdfit.pro
< prev
next >
Wrap
Text File
|
1997-07-08
|
8KB
|
250 lines
; $Id: svdfit.pro,v 1.12 1997/02/04 13:11:51 stevep Exp $
FUNCTION SVDFIT,X,Y,M, YFIT = yfit, WEIGHTS = weights, CHISQ = chisq, $
SINGULAR = sing, VARIANCE = variance, COVAR = covar, SIGMA=sigma, $
Function_name = function_name, A=A,LEGENDRE=legendre,DOUBLE=double
;+
; NAME:
; SVDFIT
;
; PURPOSE:
; Perform a general least squares fit with optional error estimates.
;
; This version uses the Numerical Recipies (2nd Edition) function
; SVDFIT. A user-supplied function or a built-in polynomial or
; legendre polynomial is fit to the data.
;
; CATEGORY:
; Curve fitting.
;
; CALLING SEQUENCE:
; Result = SVDFIT(X, Y, [M])
;
; INPUTS:
; X: A vector representing the independent variable.
;
; Y: Dependent variable vector. This vector must be same length
; as X.
;
; OPTIONAL INPUTS:
;
; M: The number of coefficients in the fitting function. For
; polynomials, M is equal to the degree of the polynomial + 1.
; If not specified and the keyword A is set, THEN
; M = N_ELEMENTS(A).
;
; INPUT KEYWORDS:
;
; A: The inital estimates of the desired coefficients. If M
; is specified, THEN A must be a vector of M elements.
; If A is specified, THEN the input M can be omitted and
; M=N_ELEMENTS(A). If not specified, the initial value
; of each coefficient is taken to be 1.0. If both M and A are
; specified, them must agree as to the number of paramaters.
;
; DOUBLE: Set this keyword to force double precision computations. This
; is helpful in reducing roundoff errors and improves the chances
; of function convergence.
;
; WEIGHTS: A vector of weights for Y[i]. This vector must be the same
; length as X and Y. If this parameter is ommitted, 1's
; (No weighting) are assumed. The error for each term is
; weighted by Weight[i] when computing the fit. Gaussian or
; instrumental uncertianties should be weighted as
; Weight = 1/Sigma where Sigma is the measurement
; error or standard deviations of Y. For Poisson or statistical
; weighting use Weight=1/Y, since Sigma=sqrt(Y).
;
; FUNCTION_NAME:
; A string that contains the name of an optional user-supplied
; basis function with M coefficients. If omitted, polynomials
; are used.
;
; The function is called: R=SVDFUNCT(X,M)
;
; where X and M are scalar values, and the function value is an
; M element vector evaluated at X with the M basis functions.
; M is the degree of the polynomial +1 if the basis functions are
; polynomials. For example, see the function SVDFUNCT or SVDLEG,
; in the IDL User Library:
;
; For more examples, see Numerical Recipes in C, second Edition,
; page 676-681.
;
; The basis function for polynomials, is R[j] = x)^j.
;
; The function must be able to return R as a FLOAT vector or
; a DOUBLE vector depending on the input type of X.
;
; LEGENDRE: Set this keyword to use the IDL function SVDLEG in the lib
; directory to fit the data to an M element legendre polynomial.
; This keyword overrides the FUNCTION_NAME keyword.
;
; OUTPUTS:
; SVDFIT returns a vector of the M coefficients fitted to the
; supplied function.
;
; OPTIONAL OUTPUT PARAMETERS:
;
; CHISQ: Sum of squared errors multiplied by weights if weights
; are specified.
;
; COVAR: Covariance matrix of the coefficients.
;
; VARIANCE: Sigma squared in estimate of each coeff(M).
; That is sqrt(VARIANCE) equals the 1 sigma deviations
; of the returned coefficients.
;
; SIGMA: The 1-sigma error estimates of the returned parameters,
; SIGMA=SQRT(VARIANCE).
;
; SINGULAR: The number of singular values returned. This value should
; be 0. If not, the basis functions do not accurately
; characterize the data.
;
; YFIT: Vector of calculated Y's.
;
; COMMON BLOCKS:
; None.
;
; SIDE EFFECTS:
; None.
;
; MODIFICATION HISTORY:
; Adapted from SVDFIT, from the book Numerical Recipes, Press,
; et. al., Page 518.
; minor error corrected April, 1992 (J.Murthy)
;
; Completely rewritten to use the actual Numerical Recipes routines
; of the 2nd Edition (V.2.06). Added the DOUBLE, SIGMA, A, and
; LEGENDRE keywords. Also changed Weight to Weights to match the
; other fitting routines.
;
; EXAMPLE:
;-
ON_ERROR,2 ;RETURN TO CALLER IF ERROR
;
; Ensure that the proper number/type of parameters are used
;
np=N_PARAMS()
HAVE_IN_A=KEYWORD_SET(A)
IF HAVE_IN_A THEN IN_A=A
IF not KEYWORD_SET(LEGENDRE) THEN use_legendre=0 else use_legendre=1
;
; Either two or three parameters must be supplied
;
IF np NE 2 and np NE 3 THEN $
MESSAGE,'Incorrect number of arguments for SVDFIT,x,y,[m]'
;
; IF 2 paramaters are supplied, THEN A must be supplied
;
IF np EQ 2 THEN $
IF N_ELEMENTS(A) eq 0 THEN $
MESSAGE,'The keyword A must be set to call SVDFIT as SVDFIT,x,y' $
ELSE M=N_ELEMENTS(A)
;
;
IF np EQ 3 THEN BEGIN
IF (SIZE(M))[0] NE 0 THEN $
MESSAGE,'The input M must be a scalar.'
IF not KEYWORD_SET(A) THEN A=REPLICATE(1.0,M) else $
IF N_ELEMENTS(A) NE M or (SIZE(A))[0] NE 1 THEN $
MESSAGE,'The keyword A must be an M element vector.'
ENDIF
IF (SIZE(X))[0] NE 1 THEN $
MESSAGE,'The input X must be a vector.'
IF (SIZE(Y))[0] NE 1 THEN $
MESSAGE,'The input Y must be a vector.'
;
; Evaluate/Set/Check a few essential paramaters
;
THRESH = 1.0E-9 ;Threshold used in editing singular values
ndata = N_ELEMENTS(x) ;SIZE of X
IF ndata NE N_ELEMENTS(y) THEN $
message, 'Error: X and Y must have same # of elements.'
IF N_ELEMENTS(weight) NE 0 THEN BEGIN
IF N_ELEMENTS(weight) NE ndata THEN $
MESSAGE, 'Error: Weights must have the number of elements as X and Y.'
sig = 1/weight ;Apply weights
ENDIF ELSE sig = FLTARR(ndata) > 1.0
IF n_elements(FUNCTION_NAME) EQ 0 THEN FUNCTION_NAME='svdfunct'
IF FUNCTION_NAME EQ '' THEN FUNCTION_NAME='svdfunct'
IF use_legendre THEN FUNCTION_NAME='svdleg'
;
; If x or y or sig or a is double precision, set use_double to true
;
If (reverse(size(a)))[1] eq 5 or $
(reverse(size(x)))[1] eq 5 or $
(reverse(size(y)))[1] eq 5 or $
(reverse(size(sig)))[1] eq 5 then use_double=1
IF not KEYWORD_SET(DOUBLE) THEN use_double=0 else use_double=1
if use_double then begin
chisq=0.0D
xx=double(x) & yy=double(y) & a=double(a)
ssig=abs(double(sig)) > 1E-12
endif else begin
chisq=0.0
xx=float(x) & yy=float(y) & a=float(a)
ssig=abs(float(sig)) > 1E-6
endelse
;
; Call the actual NR routine.
;
; Warning, direct use of this function is not supported, as
; the calling sequence is scheduled to change in a future release
; of IDL.
;
NR__SVDFIT,FUNCTION_NAME,xx,yy,ssig,ndata,A,M,COVAR,CHISQ,$
DOUBLE=use_double
;
; The variance is the diagonal elements of the covarianec matrix
;
variance=COVAR[lindgen(M)*(M+1)];
sigma=sqrt(abs(VARIANCE))
small=where(variance le max(variance)*thresh,cc)
IF cc GT 0 THEN variance[small]=0
good = where(variance GT 0, ng) ;Cutoff for sing values
sing = M - ng ;# of singular values
IF sing NE 0 THEN BEGIN
message, 'Warning: ' + strcompress(sing, /REMOVE) + $
' singular values found.',/INFORM
;
IF ng EQ 0 THEN return,undefined
ENDIF
;
; calculate YFIT
;
IF KEYWORD_SET(use_double) THEN BEGIN
yfit=DBLARR(ndata)
afunc=DBLARR(M)
ENDIF ELSE BEGIN
yfit=FLTARR(ndata)
afunc=FLTARR(M)
ENDELSE
FOR i=0,ndata-1 DO $
YFIT[i]=total(A * call_function(FUNCTION_NAME, xx[i], M))
;
; Return the fitted parameters
;
OUT_A=A
IF HAVE_IN_A THEN A=IN_A
return,OUT_A
end